package com.frontop.terminal.vlcjplayer.view.action.mediaplayer;

import com.google.common.collect.ImmutableList;
import uk.co.caprica.vlcj.player.base.AudioChannel;
import uk.co.caprica.vlcj.player.base.MediaPlayer;

import javax.swing.*;
import java.util.ArrayList;
import java.util.List;

import static com.frontop.terminal.vlcjplayer.view.action.Resource.resource;

// FIXME i think none of these actions need be public now?
//       the dynamic ones currently are unfortunately... for now... (e.g. videotrack)

// FIXME the play action here could listen to the mediaplayer and change its icon accordingly

/**
 * 媒体播放器动作
 * 这里的播放操作可以监听mediaplayer并相应地更改其图标
 *
 * @author Guodong
 */
public final class MediaPlayerActions {

    private final List<Action> playbackSpeedActions;
    private final List<Action> playbackSkipActions;
    private final List<Action> playbackChapterActions;
    private final List<Action> playbackControlActions;

    private final List<Action> audioStereoModeActions;
    private final List<Action> audioControlActions;

    private final List<Action> videoZoomActions;
    private final List<Action> videoAspectRatioActions;
    private final List<Action> videoCropActions;

    private final Action playbackPlayAction;
    private final Action playbackStopAction;

    private final Action videoSnapshotAction;

    public MediaPlayerActions(MediaPlayer mediaPlayer) {
        playbackSpeedActions = newPlaybackSpeedActions(mediaPlayer);
        playbackSkipActions = newPlaybackSkipActions(mediaPlayer);
        playbackChapterActions = newPlaybackChapterActions(mediaPlayer);
        playbackControlActions = newPlaybackControlActions(mediaPlayer);
        audioStereoModeActions = newAudioStereoModeActions(mediaPlayer);
        audioControlActions = newAudioControlActions(mediaPlayer);
        videoZoomActions = newVideoZoomActions(mediaPlayer);
        videoAspectRatioActions = newVideoAspectRatioActions(mediaPlayer);
        videoCropActions = newVideoCropActions(mediaPlayer);

        playbackPlayAction = new PlayActionAbstractMediaPlayerAction(resource("menu.playback.item.play"));
        playbackStopAction = new StopActionAbstractMediaPlayerAction(resource("menu.playback.item.stop"));
        videoSnapshotAction = new SnapshotActionAbstractMediaPlayerAction(resource("menu.video.item.snapshot"));
    }

    private List<Action> newPlaybackSpeedActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new RateActionAbstractMediaPlayerAction(resource("menu.playback.item.speed.item.x4"), 4f));
        actions.add(new RateActionAbstractMediaPlayerAction(resource("menu.playback.item.speed.item.x2"), 2f));
        actions.add(new RateActionAbstractMediaPlayerAction(resource("menu.playback.item.speed.item.normal"), 1f));
        actions.add(new RateActionAbstractMediaPlayerAction(resource("menu.playback.item.speed.item./2"), 0.5f));
        actions.add(new RateActionAbstractMediaPlayerAction(resource("menu.playback.item.speed.item./4"), 0.25f));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newPlaybackSkipActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new SkipActionAbstractMediaPlayerAction(resource("menu.playback.item.skipForward"), 10000));
        actions.add(new SkipActionAbstractMediaPlayerAction(resource("menu.playback.item.skipBackward"), -10000));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newPlaybackChapterActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new PreviousChapterActionAbstractMediaPlayerAction(resource("menu.playback.item.previousChapter")));
        actions.add(new NextChapterActionAbstractMediaPlayerAction(resource("menu.playback.item.nextChapter")));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newPlaybackControlActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new PlayActionAbstractMediaPlayerAction(resource("menu.playback.item.play")));
        actions.add(new StopActionAbstractMediaPlayerAction(resource("menu.playback.item.stop")));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newAudioStereoModeActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.unset"), AudioChannel.UNSET));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.stereo"), AudioChannel.STEREO));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.left"), AudioChannel.LEFT));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.right"), AudioChannel.RIGHT));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.reverse"), AudioChannel.RSTEREO));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.dolbys"), AudioChannel.DOLBYS));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.headphones"), AudioChannel.HEADPHONES));
        actions.add(new StereoModeActionAbstractMediaPlayerAction(resource("menu.audio.item.stereoMode.item.mono"), AudioChannel.MONO));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newAudioControlActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new VolumeActionAbstractMediaPlayerAction(resource("menu.audio.item.increaseVolume"), 10));
        actions.add(new VolumeActionAbstractMediaPlayerAction(resource("menu.audio.item.decreaseVolume"), -10));
        actions.add(new MuteActionAbstractMediaPlayerAction(resource("menu.audio.item.mute")));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newVideoZoomActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new ZoomActionAbstractMediaPlayerAction(resource("menu.video.item.zoom.item.quarter"), 0.25f));
        actions.add(new ZoomActionAbstractMediaPlayerAction(resource("menu.video.item.zoom.item.half"), 0.50f));
        actions.add(new ZoomActionAbstractMediaPlayerAction(resource("menu.video.item.zoom.item.original"), 1.00f));
        actions.add(new ZoomActionAbstractMediaPlayerAction(resource("menu.video.item.zoom.item.double"), 2.00f));
        // FIXME maybe need a zoom default of 0.0 (or is this just fit window?)
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newVideoAspectRatioActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new AspectRatioActionAbstractMediaPlayerAction(resource("menu.video.item.aspectRatio.item.default"), null));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("16:9", "16:9"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("4:3", "4:3"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("1:1", "1:1"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("16:10", "16:10"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("2.21:1", "221:100"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("2.35:1", "235:100"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("2.39:1", "239:100"));
        actions.add(new AspectRatioActionAbstractMediaPlayerAction("5:4", "5:4"));
        return ImmutableList.copyOf(actions);
    }

    private List<Action> newVideoCropActions(MediaPlayer mediaPlayer) {
        List<Action> actions = new ArrayList<>();
        actions.add(new CropActionAbstractMediaPlayerAction(resource("menu.video.item.crop.item.default"), null));
        actions.add(new CropActionAbstractMediaPlayerAction("16:10", "16:10"));
        actions.add(new CropActionAbstractMediaPlayerAction("16:9", "16:9"));
        actions.add(new CropActionAbstractMediaPlayerAction("4:3", "4:3"));
        actions.add(new CropActionAbstractMediaPlayerAction("1.85:1", "185:100"));
        actions.add(new CropActionAbstractMediaPlayerAction("2.21:1", "221:100"));
        actions.add(new CropActionAbstractMediaPlayerAction("2.35:1", "235:100"));
        actions.add(new CropActionAbstractMediaPlayerAction("2.39:1", "239:100"));
        actions.add(new CropActionAbstractMediaPlayerAction("5:3", "5:3"));
        actions.add(new CropActionAbstractMediaPlayerAction("5:4", "5:4"));
        actions.add(new CropActionAbstractMediaPlayerAction("1:1", "1:1"));
        return ImmutableList.copyOf(actions);
    }

    public List<Action> playbackSpeedActions() {
        return playbackSpeedActions;
    }

    public List<Action> playbackSkipActions() {
        return playbackSkipActions;
    }

    public List<Action> playbackChapterActions() {
        return playbackChapterActions;
    }

    public List<Action> playbackControlActions() {
        return playbackControlActions;
    }

    public List<Action> audioStereoModeActions() {
        return audioStereoModeActions;
    }

    public List<Action> audioControlActions() {
        return audioControlActions;
    }

    public List<Action> videoZoomActions() {
        return videoZoomActions;
    }

    public List<Action> videoAspectRatioActions() {
        return videoAspectRatioActions;
    }

    public List<Action> videoCropActions() {
        return videoCropActions;
    }

    public Action playbackPlayAction() {
        return playbackPlayAction;
    }

    public Action playbackStopAction() {
        return playbackStopAction;
    }

    public Action videoSnapshotAction() {
        return videoSnapshotAction;
    }

}
